<template>
    <div ref="g-tabs" class="g-tabs" @scroll="onScroll">
        <div class="focus" :style="focusStyle">
            <slot name="focus"></slot>
        </div>
        <div ref="scrollview" class="scrollview">
            <div
                    ref="g-tab"
                    v-for="(item, i) in list"
                    :key="i"
                    class="g-tab"
                    @click="selected(item, i, true)"
            >
                <slot
                        name="tab"
                        v-bind:item="item"
                        v-bind:index="i"
                        v-bind:selected="item.value == value"
                ></slot>
            </div>
        </div>
    </div>
</template>
<script>
export default {
    name: "g-tabs",
    emits: ["update:value", "change"],
    props: {
        list: {
            type: Array,
            default: () => [],
        },
        value: {
            type: [String, Number],
            default: () => "",
        },
    },
    data() {
        return {
            focusStyle: "",
            scrollLeft: 0,
            maxScrollLeft: 0,
        };
    },
    watch: {
        value(val) {
            if (val != null && val != undefined) {
                setTimeout(() => {
                    this.autoSelect();
                }, 100);
            }
        },
    },
    mounted() {
        this.autoSelect();
    },
    methods: {
        autoSelect() {
            const item = this.list.find((item) => item.value == this.value);
            const index = this.list.findIndex(
                    (item) => item.value == this.value
            );
            if (item) {
                this.selected(item, index);
            }
        },
        onScroll(e) {
            this.scrollLeft = this.$refs["g-tabs"].scrollLeft;
        },
        selected(item, index, click) {
            if (
                    this.list.findIndex((t) => t.value == this.value) == index &&
                    click
            )
                return;
            this.$emit("update:value", item.value);
            this.$emit(
                    "change",
                    item,
                    this.list.findIndex((t) => t.value == item.value)
            );
            const tabs = this.$refs["g-tab"];
            const tab = tabs[index];
            let left = 0;
            for (let i = 0; i < tabs.length; i++) {
                if (i == index) break;
                left += tabs[i].clientWidth;
            }

            const styles = {
                width: tab.clientWidth + "px",
                left: left + "px",
            };
            this.focusStyle = styles;
            const max =
                    left -
                    (this.$refs["g-tabs"].clientWidth / 2 - tab.clientWidth / 2);

            if (this.scrollLeft < max) {
                let maxScrollLeft = 0;
                for (let i = 0; i < tabs.length; i++) {
                    maxScrollLeft += tabs[i].clientWidth;
                }
                maxScrollLeft -= this.$refs.scrollview.clientWidth;
                let interval = setInterval(() => {
                    if (
                            this.scrollLeft >= max ||
                            this.scrollLeft >= maxScrollLeft
                    ) {
                        clearInterval(interval);
                    }
                    this.scrollLeft += 2;
                    this.$refs["g-tabs"].scrollLeft = this.scrollLeft;
                }, 1);
            } else if (this.scrollLeft > max) {
                let interval = setInterval(() => {
                    if (this.scrollLeft <= max || this.scrollLeft <= 0) {
                        clearInterval(interval);
                    }
                    this.scrollLeft -= 2;
                    this.$refs["g-tabs"].scrollLeft = this.scrollLeft;
                }, 1);
            }
        },
        scrollToLeft() {
            let value = 100;
            let interval = setInterval(() => {
                if (value <= 0 || this.scrollLeft <= 0) {
                    return clearInterval(interval);
                }
                this.scrollLeft -= 2;
                value -= 2;
                this.$refs["g-tabs"].scrollLeft = this.scrollLeft;
            }, 1);
        },
        scrollToRight() {
            let value = 100;
            const tabs = this.$refs["g-tab"] || [];
            let maxScrollLeft = 0;
            for (let i = 0; i < tabs.length; i++) {
                maxScrollLeft += tabs[i].clientWidth;
            }
            maxScrollLeft -= this.$refs.scrollview.clientWidth;
            let interval = setInterval(() => {
                if (value <= 0 || this.scrollLeft >= maxScrollLeft) {
                    return clearInterval(interval);
                }
                this.scrollLeft += 2;
                value -= 2;
                this.$refs["g-tabs"].scrollLeft = this.scrollLeft;
            }, 1);
        },
    },
};
</script>
<style scoped lang="scss">
.g-tabs {
    width: 100%;
    overflow: scroll;
    background: #fff;
    position: relative;

    &::-webkit-scrollbar {
        display: none;
    }

    .scrollview {
        width: auto;
        height: 100%;
        display: flex;
        flex-direction: row;
        justify-content: flex-start;
        align-items: center;
        flex-wrap: nowrap;
        position: static;
        z-index: 1;

        .g-tab {
            cursor: pointer;
            position: static;
            z-index: 1;
        }
    }

    .focus {
        position: absolute;
        left: 0;
        top: 0;
        bottom: 0;
        height: 100%;
        z-index: 0;
        transition: all 0.3s ease;
    }
}
</style>
